home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Camelot / Camelot 043 (1989-06)(Swedish User Group of Amiga)(SE)(PD)[WB].zip / Camelot 043 (1989-06)(Swedish User Group of Amiga)(SE)(PD)[WB].adf / zc / d2.c < prev    next >
C/C++ Source or Header  |  1989-03-08  |  10KB  |  643 lines

  1. /* Copyright (c) 1988 by Sozobon, Limited.  Author: Johann Ruegg
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  *
  11.  *    d2.c
  12.  *
  13.  *    Declaration subroutines
  14.  *
  15.  *    Mostly routines for initializations
  16.  */
  17.  
  18. #include <stdio.h>
  19. #include "param.h"
  20. #include "tok.h"
  21. #include "nodes.h"
  22. #include "cookie.h"
  23.  
  24. #if MMCC
  25. overlay "pass2"
  26. #endif
  27.  
  28. extern NODEP cur;
  29. extern NODEP symtab[];
  30. extern level;
  31.  
  32. extern int oflags[];
  33. #define debugi    oflags['i'-'a']
  34.  
  35. su_size(lp, cp, xp, isunion)
  36. register long *lp;
  37. char *cp;
  38. register NODE *xp;
  39. {
  40.     long sz;
  41.     char al;
  42.  
  43.     sz = xp->n_tptr->t_size;
  44.     al = xp->n_tptr->t_aln;
  45.     if (isunion) {
  46.         *lp = *lp > sz ? *lp : sz;
  47.     } else {
  48.         while (al & (*lp)) {    /* align new field */
  49.             (*lp)++;
  50.             xp->e_offs++;
  51.         }
  52.         *lp += sz;
  53.     }
  54.     *cp = *cp > al ? *cp : al;
  55. }
  56.  
  57. lc_size(lp, rp, xp)
  58. register long *lp;
  59. int *rp;
  60. register NODE *xp;
  61. {
  62.     long sz;
  63.     char al;
  64.     long arg_size();
  65.  
  66.     if (level > 1 && xp->e_sc == K_REGISTER) {
  67.         if (lc_reg(rp, xp))
  68.             return;
  69.         else
  70.             xp->e_sc = K_AUTO;
  71.     }
  72.     if (xp->e_sc == K_AUTO || level == 1) {
  73.         sz = xp->n_tptr->t_size;
  74.         al = xp->n_tptr->t_aln;
  75.         while (al & (*lp)) {    /* align new field */
  76.             (*lp)++;
  77.             xp->e_offs++;
  78.         }
  79.         if (level == 1) {
  80.             sz = arg_size(sz,xp);
  81.             xp->e_offs += ARG_BASE + *lp;
  82.         }
  83.         *lp += sz;
  84.         if (level != 1)
  85.             xp->e_offs = LOC_BASE - *lp;
  86.     }
  87. }
  88.  
  89. su_fld(lp, alp, xp, fldw, fop)
  90. register long *lp;
  91. char *alp;
  92. register NODE *xp;
  93. int *fop;
  94. {
  95.     if (*alp < ALN_I)
  96.         *alp = ALN_I;
  97.     if (fldw == 0) {
  98.         afterfld(lp, fop);
  99.         return;
  100.     }
  101.     if (fldw + *fop > 8*SIZE_I)
  102.         afterfld(lp, fop);
  103.     if (xp) {
  104.         xp->e_fldw = fldw;
  105.         xp->e_fldo = *fop;
  106.     }
  107.     *fop += fldw;
  108. }
  109.  
  110. afterfld(szp, fop)
  111. long *szp;
  112. int *fop;
  113. {
  114.     if (*fop) {
  115.         *szp += SIZE_I;
  116.         *fop = 0;
  117.     }
  118. }
  119.  
  120. ok_gsh(sc, np)
  121. NODE *np;
  122. {
  123.     if (sc == K_REGISTER || sc == K_AUTO) {
  124.         error("reg/auto outside fun");
  125.         return 0;
  126.     }
  127.     return ok_ty(np, NULL);
  128. }
  129.  
  130. ok_gx(np, endp)
  131. NODEP np, endp;
  132. {
  133.     if (np)
  134.         return ok_ty(np->n_tptr, endp);
  135.     return 0;
  136. }
  137.  
  138. ok_lsh(sc, np)
  139. NODE *np;
  140. {
  141.     return ok_ty(np, NULL);
  142. }
  143.  
  144. arytoptr(np)
  145. NODEP np;
  146. {
  147.     NODEP tp = np->n_tptr;
  148.     NODEP copyone();
  149.  
  150.     if (np->n_flags & N_COPYT) {    /* cant change if a dupl. */
  151.         tp = copyone(tp);
  152.         np->n_tptr = tp;
  153.         np->n_flags &= ~N_COPYT;
  154.     }
  155.     tp->t_token = STAR;
  156.     strcpy(tp->n_name, "Aptr to");
  157. }
  158.  
  159. ok_lx(np,endp)
  160. NODEP np, endp;
  161. {
  162.     if (np) {
  163.         if (level == 1 && np->n_tptr->t_token == '[')
  164.             arytoptr(np);
  165.         return ok_ty(np->n_tptr, endp);
  166.     }
  167.     return 0;
  168. }
  169.  
  170. ok_suh(np)
  171. NODEP np;
  172. {
  173.     return 1;
  174. }
  175.  
  176. ok_sux(np, endp)
  177. NODEP np, endp;
  178. {
  179.     if (np)
  180.         return ok_ty(np->n_tptr, endp);
  181.     return 0;
  182. }
  183.  
  184. ok_enx(np, endp)
  185. NODEP np, endp;
  186. {
  187.     if (np && np->n_tptr == endp)   /* no modifiers */
  188.         return 1;
  189.     return 0;
  190. }
  191.  
  192. ok_cast(np, endp)
  193. NODEP np, endp;
  194. {
  195.     if (np)
  196.         return ok_ty(np, endp);
  197.     return 0;
  198. }
  199.  
  200. ok_ty(np, endp)
  201. register NODEP np, endp;
  202. {
  203.     NODEP child;
  204.     long csize;
  205.     long conlval();
  206.  
  207.     if (np == endp)
  208.         return 1;
  209.     child = np->n_tptr;
  210.     if (child) {
  211.         if (ok_ty(child, endp) == 0)
  212.             return 0;
  213.         csize = child->t_size;
  214.     }
  215.  
  216.     switch (np->t_token) {
  217.     case STAR:
  218.         np->t_size = SIZE_P;
  219.         np->t_aln = ALN_P;
  220.         break;
  221.     case '(':
  222.         /* size 0 okay - fun ret void */
  223.         if (child->t_token == '[') {
  224.             error("bad func");
  225.             return 0;
  226.         }
  227.         /* size 0 */
  228.         break;
  229.     case '[':
  230.         if (csize == 0) {
  231.             error("bad array");
  232.             return 0;
  233.         }
  234.         if (np->n_right) {
  235.             csize *= conlval(np->n_right);
  236.             np->n_right = NULL;
  237.             np->t_size = csize;
  238.         }
  239.         np->t_aln = child->t_aln;
  240.         break;
  241.     default:
  242.         return 1;
  243.     }
  244.     return 1;
  245. }
  246.  
  247. ok_revx(rv,forcast)
  248. NODEP rv;
  249. {
  250.     if (rv == NULL)
  251.         return 1;
  252.     if (forcast == 0 && rv->e_token != ID) {
  253.         error("need ID");
  254.         return 0;
  255.     }
  256.     if (forcast && rv->e_token == ID) {
  257.         error("ID in cast");
  258.         return 0;
  259.     }
  260.     return 1;
  261. }
  262.  
  263. opt_ginit(xp)
  264. NODEP xp;
  265. {
  266.     if (xp->e_token != ID)
  267.         return;
  268.     if (xp->n_tptr->t_token == '(')
  269.         return;
  270.     switch (xp->e_sc) {
  271.     case K_STATIC:
  272.     case HERE_SC:
  273.         if (cur->e_token == '=') {
  274.             out_gv(xp, 0);   /* place in data segment */
  275.             fadvnode();
  276.             g_init(xp->n_tptr);
  277.         } else
  278.             out_gv(xp, 1);   /* place in BSS segment */
  279.         break;
  280. /* ? added external case ? */
  281.     case K_EXTERN:
  282.         out_gv(xp,0);
  283.     }
  284. }
  285.  
  286. opt_linit(xp)
  287. NODEP xp;
  288. {
  289.     if (xp->e_token != ID)
  290.         return;
  291.     if (xp->n_tptr->t_token == '(')
  292.         return;
  293.     switch (xp->e_sc) {
  294.     case K_STATIC:
  295.         if (cur->e_token == '=') {
  296.             out_gv(xp, 0);
  297.             fadvnode();
  298.             g_init(xp->n_tptr);
  299.         } else
  300.             out_gv(xp, 1);
  301.         to_text();
  302.         break;
  303.     case K_AUTO:
  304.     case K_REGISTER:
  305.         if (cur->e_token == '=')
  306.             a_init(xp);
  307.         break;
  308.     }
  309. }
  310.  
  311. a_init(op)
  312. NODEP op;
  313. {
  314.     register NODEP np, xp;
  315.     NODEP assignx(), copynode();
  316.  
  317.     np = cur;  advnode();
  318.     xp = assignx();
  319.     op = copynode(op);
  320.     np->n_left = op;
  321.     np->n_right = xp;
  322.     np->e_type = E_BIN;
  323.     do_expr(np, FORSIDE);
  324.     return;
  325. }
  326.  
  327. opt_enval(intp)
  328. int *intp;
  329. {
  330.     NODEP np;
  331.     NODEP questx();
  332.  
  333.     if (cur->e_token == '=') {
  334.         fadvnode();
  335.         np = questx();
  336.         *intp = conxval(np);
  337.         return;
  338.     }
  339. }
  340.  
  341. opt_field(xp,wdp,isunion)
  342. NODE *xp;
  343. int *wdp;
  344. {
  345.     NODEP np;
  346.     NODEP questx();
  347.     int i;
  348.  
  349.     *wdp = -1;
  350.     if (isunion) return;
  351.     if (cur->e_token == ':') {
  352.         fadvnode();
  353.         np = questx();
  354.         i = conxval(np);
  355.         if (i > 8*SIZE_I) {
  356.             error("field too big");
  357.             i = 8*SIZE_I;
  358.         }
  359.         if (xp) {
  360.             if (i <= 0 || bad_fty(xp->n_tptr)) {
  361.                 error("bad field");
  362.                 return;
  363.             }
  364.         } else if (i < 0) {
  365.             error("neg field width");
  366.             return;
  367.         }
  368.         *wdp = i;
  369.         return;
  370.     }
  371. }
  372.  
  373. bad_fty(tp)
  374. NODEP tp;
  375. {
  376.     int tok;
  377.  
  378.     tok = tp->t_token;
  379.     if (tok == K_INT || tok == K_UNSIGNED)
  380.         return 0;
  381.     return 1;
  382. }
  383.  
  384. field(xp, wd, ofp)
  385. NODEP xp;
  386. int *ofp;
  387. {
  388. }
  389.  
  390. NODEP
  391. def_type()
  392. {
  393.     NODEP bas_type();
  394.  
  395.     return bas_type(K_INT);
  396. }
  397.  
  398. #define NSC    LAST_SC-FIRST_SC+1
  399. #define NBAS    LAST_BAS-FIRST_BAS+1
  400.  
  401. NODE basics[NBAS];
  402. NODE str_ptr, fun_int;
  403.  
  404. struct bt {
  405.     char    *name;
  406.     int    size;
  407.     char    align;
  408. } btbl[] = {
  409.     {"Uchar",       SIZE_C, ALN_C},
  410.     {"Ulong",       SIZE_L, ALN_L},
  411.     {"Long",        SIZE_L, ALN_L},
  412.     {"Short",       SIZE_S, ALN_S},
  413.     {"Uns",         SIZE_U, ALN_U},
  414.     {"Int",         SIZE_I, ALN_I},
  415.     {"Char",        SIZE_C, ALN_C},
  416.     {"Float",       SIZE_F, ALN_F},
  417.     {"Dbl",         SIZE_D, ALN_D},
  418.     {"Void",        0},
  419. };
  420.  
  421. NODEP
  422. bas_type(btype)
  423. {
  424.     NODEP rv;
  425.     static once = 0;
  426.  
  427.     if (once == 0) {
  428.         once++;
  429.  
  430.         sprintf(str_ptr.n_name, "Ptr to");
  431.         str_ptr.t_token = STAR;
  432.         str_ptr.n_tptr = bas_type(K_CHAR);
  433.         str_ptr.n_flags = N_COPYT;
  434.         str_ptr.t_size = SIZE_P;
  435.         str_ptr.t_aln = ALN_P;
  436.  
  437.         sprintf(fun_int.n_name, "Fun ret");
  438.         fun_int.t_token = '(';
  439.         fun_int.n_tptr = bas_type(K_INT);
  440.         fun_int.n_flags = N_COPYT;
  441.     }
  442.     if (btype == SCON)
  443.         return &str_ptr;
  444.     else if (btype == '(')
  445.         return &fun_int;
  446.     rv = &basics[btype-FIRST_BAS];
  447.     if (rv->t_token == 0) {
  448.         rv->t_token = btype;
  449.         rv->t_size = btbl[btype-FIRST_BAS].size;
  450.         rv->t_aln = btbl[btype-FIRST_BAS].align;
  451.         sprintf(rv->n_name, btbl[btype-FIRST_BAS].name);
  452.     }
  453.     return rv;
  454. }
  455.  
  456. /* new function name seen in expr */
  457. NODEP
  458. new_fun(op)
  459. NODE *op;
  460. {
  461.     NODEP np;
  462.     NODEP copyone();
  463.  
  464.     /* we know left, right and tptr are NULL */
  465.     np = copyone(op); /* ID node */
  466.     np->n_tptr = bas_type('(');
  467.     np->n_flags = N_COPYT;
  468.     np->e_sc = K_EXTERN;
  469.     new_sym(symtab, np);
  470.     return np;
  471. }
  472.  
  473. /* declare arg name as int */
  474. def_arg(listpp, op)
  475. NODE **listpp, *op;
  476. {
  477.     register NODEP np;
  478.     NODEP copyone();
  479.  
  480.     np = copyone(op);
  481.     np->n_tptr = bas_type(K_INT);
  482.     np->n_flags = N_COPYT;
  483.     np->e_sc = K_AUTO;
  484.     new_sym(listpp, np);
  485. }
  486.  
  487. /* initialize 0 or 1 thing of any type (tp) */
  488. g_init(tp)
  489. register NODEP tp;
  490. {
  491.     int nsee;
  492.     long sz;
  493.     int oldsize;
  494.     int seebr = 0;
  495.  
  496.     if (cur->e_token == SCON &&
  497.            tp->t_token == '[' &&
  498.            tp->n_tptr->t_token == K_CHAR) { /* hack for SCON ary */
  499.             nsee = out_scon(cur);
  500.             fadvnode();
  501.             a_fix(tp, nsee);
  502.             return 1;
  503.     }
  504.  
  505.     if (cur->e_token == '{') {
  506.         fadvnode();
  507.         seebr = 1;
  508.     }
  509.  
  510.     switch (tp->t_token) {
  511.     case '[':
  512.         if (tp->t_size)
  513.             oldsize = tp->t_size / tp->n_tptr->t_size;
  514.         else
  515.             oldsize = 0;
  516.         nsee = inita(tp->n_tptr, oldsize);
  517.         if (nsee)
  518.             a_fix(tp, nsee);
  519.         break;
  520.     case K_STRUCT:
  521.         o_aln(tp->t_aln);
  522.         nsee = inits(tp->n_right);
  523.         break;
  524.     case K_UNION:
  525.         o_aln(tp->t_aln);
  526.         nsee = g_init(tp->n_right->n_tptr);
  527.         if (nsee) {
  528.             sz = tp->t_size - tp->n_right->n_tptr->t_size;
  529.             if (sz)
  530.                 o_nz(sz, 0);
  531.         }
  532.         break;
  533.     default:
  534.         nsee = init1(tp);
  535.         break;
  536.     }
  537.  
  538.     if (seebr) {
  539.         if (cur->e_token == ',')
  540.             fadvnode();
  541.         eat('}');
  542.     }
  543.     return nsee ? 1 : 0;
  544. }
  545.  
  546. /* initialize one (or 0) scalar to an expr */
  547. init1(tp)
  548. register NODEP tp;
  549. {
  550.     NODEP xp;
  551.     NODEP assignx();
  552.  
  553.     if (debugi) {
  554.         printf("init1");
  555.         printnode(tp);
  556.     }
  557.     xp = assignx();
  558.     if (xp) {
  559.         if (debugi)
  560.             printnode(xp);
  561.         o_vinit(tp, xp);
  562.         return 1;
  563.     } else
  564.         return 0;
  565. }
  566.  
  567. /* set array size or fill array with zeros */
  568. a_fix(tp, nsee)
  569. register NODEP tp;
  570. {
  571.     int oldsize;
  572.  
  573.     if (tp->t_size) {
  574.         oldsize = tp->t_size / tp->n_tptr->t_size;
  575.         if (oldsize > nsee) {
  576.             o_nz(tp->n_tptr->t_size * (oldsize-nsee),
  577.                 tp->n_tptr->t_aln);
  578.         } else if (oldsize < nsee) {
  579.             error("too many init exprs");
  580.         }
  581.     } else
  582.         tp->t_size = nsee * tp->n_tptr->t_size;
  583. }
  584.  
  585. /* initialize up to max items of type tp */
  586. /* if max is 0, any number is okay */
  587.  
  588. inita(tp, maxi)
  589. NODEP tp;
  590. {
  591.     int nsee;
  592.  
  593.     nsee = g_init(tp);
  594.     if (nsee == 0)
  595.         return 0;
  596.  
  597.     while (cur->e_token == ',') {
  598.         if (nsee == maxi)
  599.             break;
  600.         fadvnode();
  601.         nsee += g_init(tp);
  602.     }
  603.     return nsee;
  604. }
  605.  
  606. /* initialize (possible) structure */
  607. inits(np)
  608. register NODEP np;
  609. {
  610.     int see1;
  611.  
  612.     see1 = g_init(np->n_tptr);
  613.     if (see1 == 0)
  614.         return 0;
  615.  
  616.     while (np->n_next) {
  617.         np = np->n_next;
  618.         if (cur->e_token == ',') {
  619.             fadvnode();
  620.             see1 = g_init(np->n_tptr);
  621.         } else
  622.             see1 = 0;
  623.         if (see1 == 0)
  624.             z_init(np->n_tptr);
  625.     }
  626.  
  627.     return 1;
  628. }
  629.  
  630. z_init(tp)
  631. register NODEP tp;
  632. {
  633.     switch (tp->t_token) {
  634.     case '[':
  635.     case K_STRUCT:
  636.     case K_UNION:
  637.         o_nz(tp->t_size, tp->t_aln);
  638.         break;
  639.     default:
  640.         out_zi(tp);
  641.     }
  642. }
  643.